﻿using System.Collections.Generic;
using Acaweb.Data.Contracts;
using Acaweb.Componentes.Contracts;
using Acaweb.Data.Dao;
using System.Linq;
using Acaweb.Model.Entities.DatosCompuestos;
using Acaweb.Model.Entities;

namespace Acaweb.Componentes
{
    public class MateriasService : BaseService, IMateriasService
    {
        private IMateriasDao _MateriasDao;
        private IHistorialCursosDao _HistorialCursosDao;
        private IEstudiantesDao _EstudianteDao;
        private ICursosMatriculadosDao _CursosMatriculadosDao;
        private IPensumDao _PensumDao;
        private IPrerequisitosDao _PrerequisitosDao;
        private IHistorialEstudiantesDao _HistorialEstudiantesDao;

        public IHistorialEstudiantesDao HistorialEstudiantesDao
        {
            get { return _HistorialEstudiantesDao; }
            set { _HistorialEstudiantesDao = value; }
        }

        public IPrerequisitosDao PrerequisitosDao
        {
            get { return _PrerequisitosDao; }
            set { _PrerequisitosDao = value; }
        }

        public IEstudiantesDao EstudianteDao
        {
            get { return _EstudianteDao; }
            set { _EstudianteDao = value; }
        }

        public IHistorialCursosDao HistorialCursosDao
        {
            get { return _HistorialCursosDao; }
            set { _HistorialCursosDao = value; }
        }

        public ICursosMatriculadosDao CursosMatriculadosDao
        {
            get { return _CursosMatriculadosDao; }
            set { _CursosMatriculadosDao = value; }
        }

        public IPensumDao PensumDao
        {
            get { return _PensumDao; }
            set { _PensumDao = value; }
        }

        public IMateriasDao MateriasDao
        {
            get { return _MateriasDao; }
            set { _MateriasDao = value; }
        }

        public IList<Model.Entities.Materias> GetAll()
        {
            return MateriasDao.GetAll();
        }

        public Model.Entities.Materias GetById(int Id)
        {
            return MateriasDao.GetById(Id);
        }

        public IList<Model.Entities.Materias> MateriasHabilitadas(int CodigoEstudiante)
        {

            List<HistorialCursos> CursosAprovados = HistorialCursosDao.GetByEstudiante(CodigoEstudiante).ToList();//.Where(t => t.NotaDefinitiva > 3).ToList();
            Estudiantes Estudiante = EstudianteDao.GetByCodigoEstudiante(CodigoEstudiante);
            List<HistorialEstudiantes> Historial = HistorialEstudiantesDao.GetByEstudiante(CodigoEstudiante).ToList();
            List<Pensum> ListaPensum = PensumDao.GetByPlanEstudio(Estudiante.CodigoPlan, Historial.Last().CodigoPensum).ToList();

            CursosAprovados.ForEach(t => ListaPensum.RemoveAll(r => r.PensumPk.CodigoMateria == t.HistorialCursosPk.CodigoMateria));

            List<Materias> MateriasHabilitadas = new List<Model.Entities.Materias>();
            ListaPensum.ForEach(t => MateriasHabilitadas.Add(t.Materia));

            return MateriasHabilitadas;


            //List<CursosMatriculados> CursosMatriculados = CursosMatriculadosDao.GetByEstudiante(CodigoEstudiante).ToList().FindAll(t => CursosMatriculadosService.IsAproved(t));
            

            //List<CursosMatriculados> ListaMaterias = MigrarMaterias(Historial, CursosMatriculados);

            

            //List<Pensum> PensumHabilitadas = new List<Model.Entities.Pensum>();
            //List<Materias> MateriasHabilitadas = new List<Model.Entities.Materias>();

            //foreach (Pensum Pensum in ListaPensum)
            //{
            //    if (ListaMaterias.FindAll(t => t.CursoMatriculadoPk.CursoPk.CodigoMateria == Pensum.PensumPk.CodigoMateria).Count == 0)
            //    {
            //        List<Prerequisitos> ListaPrerequisito = PrerequisitosDao.GetMaterias(Pensum.PensumPk.CodigoMateria, Pensum.PensumPk.CodigoPlan,
            //            Pensum.PensumPk.CodigoPensum).ToList();

            //        if (ListaPrerequisito.Count == 0)
            //            PensumHabilitadas.Add(Pensum);
            //        else
            //            if (ListaPrerequisito.FindAll(t => CursosMatriculados.FindAll(r => r.Curso.Materia.CodigoMateria == t.PrerequisitoPk.CodigoPrerequisito).Count > 0).Count == 0)
            //                PensumHabilitadas.Add(Pensum);
            //    }
            //}

            //PensumHabilitadas.ForEach(t => MateriasHabilitadas.Add(t.Materia));

            //return MateriasHabilitadas;
        }

        private List<int> GroupByPensum(List<Acaweb.Model.Entities.HistorialEstudiantes> Lista)
        {
            List<int> ListaInt = new List<int>();

            Lista.GroupBy<Acaweb.Model.Entities.HistorialEstudiantes, int>(t => t.CodigoPensum).ToList().ForEach(t => ListaInt.Add(t.Key));

            return ListaInt;
        }

        private List<CursosMatriculados> MigrarMaterias(List<HistorialEstudiantes> Historial, List<CursosMatriculados> ListaCursosMatriculados)
        {
            List<CursosMatriculados> ListaMateriasCursadas = new List<CursosMatriculados>();

            if (GroupByPensum(Historial).Count > 1)
            {
                int LastCodigoPensum = Historial.Last().CodigoPensum;

                foreach (HistorialEstudiantes Semestre in Historial)
                {
                    if (Semestre.CodigoPensum == LastCodigoPensum)
                    {
                        ListaCursosMatriculados.FindAll(t => t.CursoMatriculadoPk.CursoPk.PerdiodoAcademico == Semestre.HistorialEstudiantePk.PeriodoAcademico).ForEach
                            (t => ListaMateriasCursadas.Add(t));
                    }
                    else
                    {

                        foreach (CursosMatriculados CM in ListaCursosMatriculados.FindAll(t => t.CursoMatriculadoPk.CursoPk.PerdiodoAcademico == Semestre.HistorialEstudiantePk.PeriodoAcademico))
                        {
                            Materias Materia = MateriaEquivalente(CM.CursoMatriculadoPk.CursoPk.CodigoMateria, PensumDao.GetById(new PensumPk
                            {
                                CodigoMateria = CM.CursoMatriculadoPk.CursoPk.CodigoMateria,
                                CodigoPensum = Semestre.CodigoPensum,
                                CodigoPlan = CM.CursoMatriculadoPk.CursoPk.CodigoPlan
                            }));
                            CM.Curso.Materia = Materia;
                            if (Materia != null)
                                ListaMateriasCursadas.Add(CM);
                        }
                    }
                }
            }
            else
            {
                ListaCursosMatriculados.ForEach(t => ListaMateriasCursadas.Add(t));
            }

            return ListaMateriasCursadas;
        }

        private Materias MateriaEquivalente(int CodigoMateria, Pensum Pensum)
        {
            if (Pensum.MateriaEquivalente != 0)
            {
                Pensum.PensumPk.CodigoMateria = Pensum.MateriaEquivalente;
                PensumDao.GetById(Pensum.PensumPk);
                if (Pensum.PensumPk.CodigoMateria == CodigoMateria)
                    return Pensum.Materia;
                else
                    return MateriaEquivalente(CodigoMateria, Pensum);
            }
            else
                return null;
        }
    }
}